package com.pureut.storage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.storage.domain.*;
import com.pureut.storage.dto.IncomingMaterialPrintingDetailDto;
import com.pureut.storage.dto.IncomingMaterialPrintingDto;
import com.pureut.storage.dto.WarehouseStringDto;
import com.pureut.storage.mapper.*;
import com.pureut.storage.service.*;
import com.pureut.storage.utils.DocumentTypeEnum;
import com.pureut.storage.vo.IncomingMaterialPrintingVo;
import com.pureut.storage.vo.OneKeyWarehousingVo;
import com.pureut.storage.vo.UpdatePrintStatusVo;
import com.pureut.system.api.OrderFeignService;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.api.vo.ResultMaterialVo;
import com.pureut.system.api.vo.ReturnStatusVo;
import com.pureut.system.api.vo.UpdatePurchaseOrderDataVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/***
 *
 * Author:C
 * Date:2022/12/26 14:57
 * @DESC
 */
@Service
public class IncomingMaterialPrintingServiceImpl extends ServiceImpl<IncomingMaterialPrintingMapper, IncomingMaterialPrinting> implements IncomingMaterialPrintingService {

    @Resource
    IncomingMaterialPrintingMapper incomingMaterialPrintingMapper;

    @Resource
    IncomingMaterialPrintingDetailService incomingMaterialPrintingDetailService;

    @Resource
    IncomingMaterialPrintingDetailMapper incomingMaterialPrintingDetailMapper;

    @Resource
    PurchaseReceiptService purchaseReceiptService;

    @Resource
    PurchaseReceiptDetailMapper purchaseReceiptDetailMapper;

    @Resource
    PurchaseReceiptDetailService purchaseReceiptDetailService;

    @Resource
    WmsStockInfoMapper wmsStockInfoMapper;

    @Resource
    WmsStockInfoService wmsStockInfoService;

    @Resource
    WarehouseService warehouseService;

    @Resource
    PublicGoodsMapper publicGoodsMapper;

    @Resource
    OrderFeignService orderFeignService;

    @Resource
    IncomingMaterialSubcontractPrintingMapper incomingMaterialSubcontractPrintingMapper;


    /**
     * 采购列表
     *
     * @param incomingMaterialPrintingVo
     * @return
     */
    @Override
    @DataScope(deptAlias = "a")
    public List<IncomingMaterialPrintingDto> getIncomingMaterial(IncomingMaterialPrintingVo incomingMaterialPrintingVo) {
        List<IncomingMaterialPrintingDto> list = incomingMaterialPrintingMapper.getList(incomingMaterialPrintingVo);

        //获取采购打印状态
        List<SysDictData> printArray = DictUtils.getDictCache("print_status");
        Map<String, String> printMap = printArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        for (IncomingMaterialPrintingDto entity : list) {
            //获取采购打印状态
            entity.setPrintStatusDict(printMap.get(String.valueOf(entity.getPrintStatus())));
            entity.setDocumentTypeDict(DocumentTypeEnum.getValue(Integer.parseInt(entity.getDocumentType())));
        }
        return list;
    }

    /**
     * 采购打印详情
     *
     * @param id
     * @return
     */
    @Override
    public IncomingMaterialPrintingDto getPrintView(long id) {

        IncomingMaterialPrintingDto incomingMaterialPrintingDto = incomingMaterialPrintingMapper.getPrintById(id);
        //获取该数据下的明细
        List<IncomingMaterialPrintingDetail> incomingMaterialPrintingDetails = incomingMaterialPrintingDetailMapper.selectList(new QueryWrapper<IncomingMaterialPrintingDetail>().lambda().eq(IncomingMaterialPrintingDetail::getPrintId, id));
        BigDecimal totalWeight = new BigDecimal(0);
        for (IncomingMaterialPrintingDetail entity : incomingMaterialPrintingDetails) {
            totalWeight = totalWeight.add(new BigDecimal(String.valueOf(entity.getNetWeight())));
        }
        //计算平均净重
        BigDecimal divide = totalWeight.divide(new BigDecimal(incomingMaterialPrintingDto.getQuantityBatch()), 0);
        incomingMaterialPrintingDto
                //本批净重
                .setNetWeight(Double.parseDouble(totalWeight.toString()))
                //本批数量
                .setQuantityBatch(incomingMaterialPrintingDto.getQuantityBatch())
                //平均净重
                .setAverageNetWeight(Double.parseDouble(divide.toString()));
        return incomingMaterialPrintingDto;
    }


    /**
     * 一键入库
     *
     * @param oneKeyWarehousingVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean oneKeyWarehousing(OneKeyWarehousingVo oneKeyWarehousingVo) {
        //通过库位编码获取仓库信息
        WarehouseStringDto warehouseCode = warehouseService.getWarehouseCode(oneKeyWarehousingVo.getKwCode());
        //获取采购打印信息
        IncomingMaterialPrinting incomingMaterialPrinting = getById(oneKeyWarehousingVo.getId());
        if (incomingMaterialPrinting.getPrintStatus() == 3) {
            //获取采购打印明细信息
            List<IncomingMaterialPrintingDetailDto> detailList = incomingMaterialPrintingDetailService.getDetailList(oneKeyWarehousingVo.getId());

            //根据批次号查询采购入库明细
            List<PurchaseReceiptDetail> purchaseReceiptDetailList = purchaseReceiptDetailMapper.selectList(new QueryWrapper<PurchaseReceiptDetail>().lambda().eq(PurchaseReceiptDetail::getBatchNo, detailList.get(0).getBatchNo()));
            for (PurchaseReceiptDetail entity : purchaseReceiptDetailList) {
                entity.setStatus(2);
                entity.setWarehouseInBy(SecurityUtils.getUsername());
                entity.setWarehouseMessage(warehouseCode.getCombinationName());
                entity.setWarehouseInTime(new Date());
            }
            //修改采购入库明细信息状态为已入库
            purchaseReceiptDetailService.updateBatchById(purchaseReceiptDetailList);

            //获取采购入库信息
            PurchaseReceipt byId = purchaseReceiptService.getById(purchaseReceiptDetailList.get(0).getReceiptId());

            //获取仓库数据
            List<WmsStockInfo> wmsStockInfoList = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialBatch, purchaseReceiptDetailList.get(0).getBatchNo()));
            for (WmsStockInfo entity : wmsStockInfoList) {

                entity.setWsiWarehourse(String.valueOf(warehouseCode.getCkId()));
                entity.setWsiReservoirArea(String.valueOf(warehouseCode.getKqId()));
                entity.setWsiStorageLoaction(String.valueOf(warehouseCode.getKwId()));
                entity.setWsiWarehourseInfo(warehouseCode.getCombinationName());
                entity.setWsiDocNum(byId.getReceiptNo());
                entity.setWsiConnectNum(byId.getPurchaseOrderNo());
                entity.setWsiGorssWeight(purchaseReceiptDetailList.get(0).getGrossWeight());
                entity.setWsiNetWeight(purchaseReceiptDetailList.get(0).getNetWeight());
                entity.setWsiMaterialStatus(2);
                entity.setWsiMaterialGrade("1");
            }
            //修改仓库数据
            wmsStockInfoService.updateBatchById(wmsStockInfoList);

            //获取入库总重量
            BigDecimal totalNetWeight = new BigDecimal(0);
            for (WmsStockInfo entity : wmsStockInfoList) {
                totalNetWeight = totalNetWeight.add(new BigDecimal(String.valueOf(entity.getWsiNetWeight())));
            }
            //判断该物料的单位
            PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, byId.getMaterialCode()));

            //校验该采购入库的全部明细状态是否都为已入库，如果不全是就修改为入库中，否则就修改为已完成
            List<PurchaseReceiptDetail> receiptDetailList = purchaseReceiptDetailMapper.selectList(new QueryWrapper<PurchaseReceiptDetail>().lambda().eq(PurchaseReceiptDetail::getReceiptId, byId.getId()));
            boolean isTrue = true;
            for (PurchaseReceiptDetail entity : receiptDetailList) {
                if (entity.getStatus() == 1) {
                    isTrue = false;
                    break;
                }
            }
            //获取本次入库的重量与单据原重量之和
            double v;
            if (byId.getWarehousingWeight() != 0) {
                BigDecimal add = totalNetWeight.add(new BigDecimal(String.valueOf(byId.getWarehousingWeight())));
                v = Double.parseDouble(add.toString());
            } else {
                v = Double.parseDouble(totalNetWeight.toString());
            }

            //单位为千克
            boolean b;
            if ("2".equals(publicGoods.getMaterialUnit())) {

                byId.setActualQuantity(String.valueOf(v));
                byId.setWarehousingWeight(v);
                int i = byId.getWarehousingNum() + wmsStockInfoList.size();
                byId.setWarehousingNum(i);

//                //物料单位是千克
//                double plannedWeight = byId.getPlannedWeight();
//                b = Double.parseDouble(byId.getActualQuantity()) >= plannedWeight;
//                if (isTrue && b) {
//                    byId.setStatus(3);
//
//                } else {
//                    byId.setStatus(2);
//                }
//                purchaseReceiptService.updateById(byId);
            } else if ("3".equals(publicGoods.getMaterialUnit())) {

                //如果单位是吨,那么实际重量是出库重量/1000
                BigDecimal bigDecimal = new BigDecimal("1000");
                BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(v));
                BigDecimal divide = bigDecimal1.divide(bigDecimal);

                byId.setActualQuantity(divide.toString());
                byId.setWarehousingWeight(v);
                int i = byId.getWarehousingNum() + wmsStockInfoList.size();
                byId.setWarehousingNum(i);

//                //物料单位是千克
//                double plannedWeight = byId.getPlannedWeight();
//                b = Double.parseDouble(byId.getActualQuantity()) >= plannedWeight;
//                if (isTrue && b) {
//                    byId.setStatus(3);
//
//                } else {
//                    byId.setStatus(2);
//
//                }
//                purchaseReceiptService.updateById(byId);
            } else {
                byId.setWarehousingWeight(v);
                int i = byId.getWarehousingNum() + wmsStockInfoList.size();
                byId.setActualQuantity(String.valueOf(i));
                byId.setWarehousingNum(i);
            }

            //物料单位不是千克
            double plannedWeight = byId.getPlannedWeight();
            b = Double.parseDouble(byId.getActualQuantity()) >= plannedWeight;
            if (isTrue && b) {
                byId.setStatus(3);
            } else {
                byId.setStatus(2);
            }
            purchaseReceiptService.updateById(byId);

            // 将数据回传至采购订单
            if (byId.getStatus() == 3) {
                UpdatePurchaseOrderDataVo updatePurchaseOrderDataVo = new UpdatePurchaseOrderDataVo();
                updatePurchaseOrderDataVo.setActualQuantity(byId.getActualQuantity());
                updatePurchaseOrderDataVo.setPurchaseOrderNo(byId.getPurchaseOrderNo());
                orderFeignService.updateOrderData(updatePurchaseOrderDataVo);
            }
            incomingMaterialPrinting.setPrintStatus(4);
            return updateById(incomingMaterialPrinting);
        } else {
            throw new GlobalException("只能操作待入库的数据");
        }
    }


    /**
     * 根据唯一标识修改状态(feign调用)
     *
     * @param returnStatusVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean getDataByOnlyMark(ReturnStatusVo returnStatusVo) {

        IncomingMaterialPrinting incomingMaterialPrinting = incomingMaterialPrintingMapper.selectOne(new QueryWrapper<IncomingMaterialPrinting>().lambda().eq(IncomingMaterialPrinting::getOnlyMark, returnStatusVo.getOnlyMark()));

        incomingMaterialPrinting.setPrintStatus(2);
        List<ResultMaterialVo> materialList = returnStatusVo.getMaterialList();
        String averageTare = materialList.get(0).getAverageTare();

        //根据id获取明细数据
        List<IncomingMaterialPrintingDetail> incomingMaterialPrintingDetails = incomingMaterialPrintingDetailMapper.selectList(new QueryWrapper<IncomingMaterialPrintingDetail>().lambda().eq(IncomingMaterialPrintingDetail::getPrintId, incomingMaterialPrinting.getId()));
        for (IncomingMaterialPrintingDetail entity : incomingMaterialPrintingDetails) {
            //毛重 - 皮重
//            int round = (int) Math.round(entity.getGrossWeight());
//            int integer = Integer.parseInt(averageTare);
//            BigDecimal subtract = new BigDecimal(String.valueOf(round)).subtract(new BigDecimal(integer));
//            String s = subtract.toString();
            entity.setNetWeight(entity.getGrossWeight());
        }
//        for (IncomingMaterialPrintingDetail detail : incomingMaterialPrintingDetails) {
//            for (ResultMaterialVo materialVo : materialList) {
//                if (detail.getMaterialNumber().equals(materialVo.getMaterialNumber())) {
//                    //毛重 - 皮重
//                    int round = (int) Math.round(detail.getGrossWeight());
//                    int integer = Integer.parseInt(materialVo.getAverageTare());
//                    if (round >= integer) {
//                        //将该批次下的物料净重都进行修改
//
//                        BigDecimal subtract = new BigDecimal(String.valueOf(detail.getGrossWeight())).subtract(new BigDecimal(materialVo.getAverageTare()));
//                        detail.setNetWeight(Double.parseDouble(subtract.toString()));
//                    } else {
//                        //将该批次下的物料净重都进行修改
//                        detail.setNetWeight(detail.getGrossWeight());
//                    }
//                }
//            }
//        }
        incomingMaterialPrintingDetailService.updateBatchById(incomingMaterialPrintingDetails);
        return updateById(incomingMaterialPrinting);
    }

    /**
     * 根据唯一标识获取采购入库单号(feign调用)
     *
     * @param onlyMark
     * @return
     */
    @Override
    public String getReceiptNo(String onlyMark) {
        IncomingMaterialPrinting incomingMaterialPrinting = incomingMaterialPrintingMapper.selectOne(new QueryWrapper<IncomingMaterialPrinting>().lambda().eq(IncomingMaterialPrinting::getOnlyMark, onlyMark));
        return incomingMaterialPrinting.getReceiptNo();
    }

    /**
     * 根据批次号修改来料打印状态(feign调用)
     *
     * @param updatePrintStatusVo
     */
    @Override
    public void updatePrintStatus(UpdatePrintStatusVo updatePrintStatusVo) {

        //批次号
        String batchNo = "";

        IncomingMaterialPrinting incomingMaterialPrinting = incomingMaterialPrintingMapper.selectOne(new QueryWrapper<IncomingMaterialPrinting>().lambda().eq(IncomingMaterialPrinting::getBatchNo, updatePrintStatusVo.getBatchNumber()));
        if (incomingMaterialPrinting != null) {
            incomingMaterialPrinting.setPrintStatus(2);
            updateById(incomingMaterialPrinting);

            //批次号
            batchNo = incomingMaterialPrinting.getBatchNo();
        }

        IncomingMaterialSubcontractPrinting incomingMaterialSubcontractPrinting = incomingMaterialSubcontractPrintingMapper.selectOne(new QueryWrapper<IncomingMaterialSubcontractPrinting>().lambda().eq(IncomingMaterialSubcontractPrinting::getBatchNo, updatePrintStatusVo.getBatchNumber()));
        if (incomingMaterialSubcontractPrinting != null) {
            incomingMaterialSubcontractPrinting.setPrintStatus(2);
            incomingMaterialSubcontractPrintingMapper.updateById(incomingMaterialSubcontractPrinting);

            //批次号
            batchNo = incomingMaterialSubcontractPrinting.getBatchNo();
        }


        //同时获取对应明细下的数据，修改净重数量
        List<IncomingMaterialPrintingDetail> incomingMaterialPrintingDetails = incomingMaterialPrintingDetailMapper.selectList(new QueryWrapper<IncomingMaterialPrintingDetail>().lambda().eq(IncomingMaterialPrintingDetail::getBatchNo, batchNo));

        if (incomingMaterialPrintingDetails!=null&&incomingMaterialPrintingDetails.size()!=0) {
            double grossWeight = incomingMaterialPrintingDetails.get(0).getGrossWeight();
            for (IncomingMaterialPrintingDetail entity : incomingMaterialPrintingDetails) {
                entity.setNetWeight(grossWeight);
            }
            incomingMaterialPrintingDetailService.updateBatchById(incomingMaterialPrintingDetails);
        }

    }
}
